﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;

namespace TC
{
    public class Entry : FlowNode
    {
        public FlowOutput<FlowNode> flowOut;

        public override void OnCreate()
        {
            flowOut = this.AddFlowOutPort<FlowNode>("Out");
        }
    }

    public class Result : FlowNode
    {
        public FlowInput<FlowNode> flowIn;

        public override void OnCreate()
        {
            flowIn = this.AddFlowInPort<FlowNode>("In");
        }
    }

    /// <summary>
    /// 封装一段逻辑
    /// </summary>
    public class FunctionGraph : Graph
    {
        public Dictionary<string, Variable> ins;//输入参数
        public Dictionary<string, Variable> outs;//输出参数

        public Entry begin;
        public Result end;

        public FunctionGraph(Context context, Dispatcher dispatcher) : base(context, dispatcher)
        {
        }

        public override void OnCreate()
        {
            base.OnCreate();

            foreach (var i in ins)
            {
                _addIn(i.Key, i.Value);
            }

            foreach (var i in outs)
            {
                _addOut(i.Key, i.Value);
            }
        }

        public void Call(Dispatcher chain)
        {
            chain.Call(begin);
        }

        private void _addOut(string name, Variable value)
        {
            if (value is ByteVar)
            {
                end.AddValueInPort<byte>(name);
            }
            else if (value is ShortVar)
            {
                end.AddValueInPort<short>(name);
            }
            else if (value is IntVar)
            {
                end.AddValueInPort<int>(name);
            }
            else if (value is LongVar)
            {
                end.AddValueInPort<long>(name);
            }
            else if (value is FloatVar)
            {
                end.AddValueInPort<float>(name);
            }
            else if (value is CharVar)
            {
                end.AddValueInPort<char>(name);
            }
            else if (value is BoolVar)
            {
                end.AddValueInPort<bool>(name);
            }
            else if (value is VectorVar)
            {
                end.AddValueInPort<Vector3>(name);
            }
            else
            {
                end.AddValueInPort<object>(name);
            }
        }

        private void _addIn(string name, Variable value)
        {
            if (value is ByteVar)
            {
                begin.AddValueOutPort<byte>(name, () => { return ins[name].AsByte(); });
            }
            else if (value is ShortVar)
            {
                begin.AddValueOutPort<short>(name, () => { return ins[name].AsShort(); });
            }
            else if (value is IntVar)
            {
                begin.AddValueOutPort<int>(name, () => { return ins[name].AsInt(); });
            }
            else if (value is LongVar)
            {
                begin.AddValueOutPort<long>(name, () => { return ins[name].AsLong(); });
            }
            else if (value is FloatVar)
            {
                begin.AddValueOutPort<float>(name, () => { return ins[name].AsFloat(); });
            }
            else if (value is CharVar)
            {
                begin.AddValueOutPort<char>(name, () => { return ins[name].AsChar(); });
            }
            else if (value is BoolVar)
            {
                begin.AddValueOutPort<bool>(name, () => { return ins[name].AsBool(); });
            }
            else if (value is VectorVar)
            {
                begin.AddValueOutPort<Vector3>(name, () => { return ins[name].AsVector3(); });
            }
            else
            {
                begin.AddValueOutPort<object>(name, () => { return ins[name].AsObject<object>(); });
            }
        }
    }
}
